package com.ihr360.payroll.model.dto.salary.task.period;

import com.ihr360.common.DateRange;
import com.ihr360.payroll.model.base.salaryreport.IPayPeriod;
import com.ihr360.payroll.model.dto.salary.plan.SalaryPlan;
import com.ihr360.payroll.type.PeriodState;
import com.ihr360.payroll.type.ReportState;
import com.ihr360.shared.entitywithlistener.NumberIdWithTimeAndCompanyId;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 激活状态的薪酬账期
 */
@Entity
public class ActivePayPeriod extends NumberIdWithTimeAndCompanyId<Long>  implements IPayPeriod {

    /**
     * 薪资方案
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = false, unique = true)
    protected SalaryPlan salaryPlan;

    //It can be removed
    //private boolean firstPeriod;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    private PayPeriodTerm currentTerm;

    //？？？最后一个账期是否用于算税使用？？？？
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    private PayPeriodTerm lastTerm;

    /**
     * 薪资周期
     */
    @Column(nullable = false, columnDefinition = "DATE")
    private Date startOn;

    @Column(nullable = false, columnDefinition = "DATE")
    private Date endOn;


    private int year;

    private int month;


    /**
     * 考勤周期
     */
    @Column(nullable = false, columnDefinition = "DATE")
    private Date attendanceStartOn;

    @Column(nullable = false, columnDefinition = "DATE")
    private Date attendanceEndOn;

    @OneToMany(mappedBy = "payPeriod", fetch = FetchType.EAGER,
            cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    @OrderBy("startOn")
    private List<PayPeriodTerm> terms = new ArrayList<>();

    @Enumerated(EnumType.STRING)
    @Column(nullable = false, length = 40)
    private PeriodState state = PeriodState.STAFF_CHECKING;

    /**
     * 关联审批记录id
     * */
    @Column(length = 40)
    private String applicationId;


    public boolean isReportsCreated() {
        if (null != currentTerm && null != lastTerm && currentTerm == lastTerm) {
            return lastTerm.isReportCreated();
        }
        return false;
    }

    public boolean isCurrentTermReportCreated() {
        return getCurrentTermReportState() == ReportState.FINISHED;
    }

    public ReportState getCurrentTermReportState() {
        if (null != currentTerm) {
            return currentTerm.getReportState();
        }
        return ReportState.UNSTARTED;
    }

    public SalaryPlan getSalaryPlan() {
        return salaryPlan;
    }

    public void setSalaryPlan(SalaryPlan salaryPlan) {
        this.salaryPlan = salaryPlan;
    }

    public PayPeriodTerm getCurrentTerm() {
        return currentTerm;
    }

    public void setCurrentTerm(PayPeriodTerm currentTerm) {
        this.currentTerm = currentTerm;
    }

    public PayPeriodTerm getLastTerm() {
        return lastTerm;
    }

    public void setLastTerm(PayPeriodTerm lastTerm) {
        this.lastTerm = lastTerm;
    }

    public Date getStartOn() {
        return startOn;
    }

    public void setStartOn(Date startOn) {
        this.startOn = startOn;
    }

    public Date getEndOn() {
        return endOn;
    }

    public void setEndOn(Date endOn) {
        this.endOn = endOn;
    }


    public int getYear() {
        if (year == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startOn);
            year = calendar.get(Calendar.YEAR);
        }
        return year;
    }

    public int getMonth() {
        if (month == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startOn);
            month = calendar.get(Calendar.MONTH) + 1;
        }
        return month;
    }

    public void setYear(int year) {
        if (year == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startOn);
            year = calendar.get(Calendar.YEAR);
        }
        this.year = year;
    }

    public void setMonth(int month) {
        if (month == 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startOn);
            month = calendar.get(Calendar.MONTH) + 1;
        }
        this.month = month;
    }


    public List<PayPeriodTerm> getTerms() {
        return terms;
    }

    public void setTerms(List<PayPeriodTerm> terms) {
        this.terms = terms;
    }

    public PeriodState getState() {
        return state;
    }

    public void setState(PeriodState state) {
        this.state = state;
    }

    public Date getAttendanceStartOn() {
        return attendanceStartOn != null ? attendanceStartOn : startOn;
    }

    public void setAttendanceStartOn(Date attendanceStartOn) {
        this.attendanceStartOn = attendanceStartOn;
    }

    public Date getAttendanceEndOn() {
        return attendanceEndOn != null ? attendanceEndOn : endOn;
    }

    public void setAttendanceEndOn(Date attendanceEndOn) {
        this.attendanceEndOn = attendanceEndOn;
    }

    public String getApplicationId() {
        return applicationId;
    }

    public void setApplicationId(String applicationId) {
        this.applicationId = applicationId;
    }

    /**
     * 获取考勤周期和薪资周期的并集
     *
     * @return
     */
    public DateRange unionPeriodRange() {
        Date start = attendanceStartOn.before(startOn) ? attendanceStartOn : startOn;
        Date end = attendanceEndOn.after(endOn) ? attendanceEndOn : endOn;
        return DateRange.build(start, end);
    }
}